﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Drawing;

/// <summary>
/// Summary description for Transform
/// </summary>
public class Transform
{
    //private static readonly int _DEFAULT_LEVEL	    = 12;
    private static readonly int _MAX_CLOSE_UP_LEVEL = 17;
    //private static readonly int _MIN_MAP_LEVEL = 5;
    //private static readonly int _MAX_MAP_LEVEL = 19;
    //private static readonly int _LEVEL_DRAW_ICON_16 = 13;
    //private static readonly int _LEVEL_DRAW_ICON_8 = 11;

    public int m_nWidth;	
	public int m_nHeight;
    //CArray<double> m_Scales;
	public WorldTileProjection	m_pProj;
	public Rect2D	m_rcMap;

	public Transform()
    {
	    m_pProj = new WorldTileProjection();
	    //m_nIPR = 10000;
	    m_nWidth = 256;
	    m_nHeight = 256;
    }

    public void Setup(Rectangle viewRect, int nMapLevel, double dWorldCenterX, double dWorldCenterY)
    {
	    Rect2D vwRect = new Rect2D((double)viewRect.Left, (double)viewRect.Bottom, 
					    (double)viewRect.Right, (double)viewRect.Top);

	    m_pProj.SetRectView (vwRect);
	    m_pProj.SetLevel(nMapLevel);
	    m_pProj.SetCenter(dWorldCenterX, dWorldCenterY);
    }

    public void SetView(Rectangle viewRect)
    {
	    Rect2D vwRect = new Rect2D((double)viewRect.Left, (double)viewRect.Bottom, 
					    (double)viewRect.Right, (double)viewRect.Top);

	    m_pProj.SetRectView(vwRect);
    }

    public Rect2D GetWorldRect()
    {
	    Rect2D viewRect = m_pProj.GetViewRect();
	    return m_pProj.RDisplay2RR(viewRect);
    }

    public void SetMapLevel(int nLevel)
    {
	    if(m_pProj != null)
		    m_pProj.SetLevel(nLevel);
    }

    public int GetMapLevel()
    {
	    return m_pProj.GetLevel();
    }

    public void SetWorldCenter(Point2D point)
    {
	    m_pProj.SetCenter(point);
    }

    public Point2D GetWorldCenter()
    {
	    return m_pProj.GetCenterPoint();
    }

    public Point GetTileCoord(int nVx, int nVy)
    {
	    Point2D rpoint =  m_pProj.PDisplay2RP(nVx, nVy);
	    return m_pProj.GetTileCoords(rpoint);
    }

    public Point2D W2V(Point2D wPt)
    {
	    return m_pProj.RP2PDisplay(wPt);
    }

    public Point2D W2V(double dWx, double dWy)
    {
	    return m_pProj.RP2PDisplay(dWx, dWy);
    }

    public void W2V(Point2D wPt, Point vPt)
    {
	    m_pProj.RP2PDisplay(wPt, vPt);
    }

    public Rect2D W2V(Rect2D wRect)
    {
	    return m_pProj.RR2RDisplay(wRect);
    }

    public void W2V(Rect2D wRect, Rectangle vRect)
    {
	    m_pProj.RR2RDisplay(wRect, vRect);
    }


    public Point2D V2W(Point2D vPt)
    {
	    return m_pProj.PDisplay2RP(vPt);
    }

    public Point2D V2W(Point vPt)
    {
	    return m_pProj.PDisplay2RP(vPt.X, vPt.Y);
    }

    public Point2D V2W(double dVx, double dVy)
    {
	    return m_pProj.PDisplay2RP((int)dVx, (int)dVy);
    }

    public Rect2D V2W(Rect2D vRect)
    {
	    return m_pProj.RDisplay2RR(vRect);
    }

    public Rect2D V2W(Rectangle vRect)
    {
	    return m_pProj.RDisplay2RR(vRect);
    }

    public void W2V(Point2D[] wPt, Point2D[] vPt, int nSize)
    {
	    m_pProj.RP2PDisplay(wPt, vPt, nSize);
    }

    public void W2V(Point2D[] wPt, Point[] vPt, int nSize)
    {
	    m_pProj.RP2PDisplay(wPt, vPt, nSize);
    }

    /*void W2V(Point2D[] wPt, Point[] vPt, int nSize)
    {
	    m_pProj.RP2PDisplay(wPt, vPt, nSize);
    }*/

    /*void W2V(Point2D[] wPt, Point[] vPt)
    {
	    m_pProj.RP2PDisplay(wPt, vPt);
    }*/

    public void V2W(Point2D[] vPt, Point2D[] wPt, int nSize)
    {
	    m_pProj.PDisplay2RP(vPt, wPt, nSize);
    }

    public void V2W(Point[] vPt, Point2D[] wPt, int nSize)
    {
	    m_pProj.PDisplay2RP(vPt, wPt, nSize);
    }

    /*void V2W(Point[] vPt, Point2D[] wPt, int nSize)
    {
	    m_pProj.PDisplay2RP(vPt, wPt, nSize);
    }*/

    public void ZoomPan(Point sPoint, Point ePoint, Rectangle vRect)
    {
	    Point2D svPoint = new Point2D(sPoint.X, sPoint.Y);
        Point2D evPoint = new Point2D(ePoint.X, ePoint.Y);

	    Point2D srPoint = m_pProj.PDisplay2RP(svPoint);
	    Point2D erPoint = m_pProj.PDisplay2RP(evPoint);

	    double dLonWidth  = erPoint.x - srPoint.x;
	    double dLatHeight = erPoint.y - srPoint.y;

	    Point2D ptCenter = m_pProj.GetCenterPoint();
	    ptCenter.x -= dLonWidth;
	    ptCenter.y -= dLatHeight;

	    m_pProj.SetCenter(ptCenter);
    }

    public bool ZoomIn(Point vPoint)
    {
	    if(m_pProj.IsValidLevel(m_pProj.GetLevel() + 1))
	    {
		    Point2D firstPt = m_pProj.PDisplay2RP(vPoint.X, vPoint.Y);

		    int nCurLevel = m_pProj.GetLevel();
		    m_pProj.SetLevel(nCurLevel+1);

		    Point2D latterPt = m_pProj.PDisplay2RP(vPoint.X, vPoint.Y);
		    Point2D centerPt = m_pProj.GetCenterPoint();

		    centerPt.x += firstPt.x - latterPt.x;
		    centerPt.y += firstPt.y - latterPt.y;
    		
		    m_pProj.SetCenter(centerPt);
		    return true;
	    }

	    return false;
    }

    public bool ZoomOut(Point vPoint)
    {
	    if(m_pProj.IsValidLevel(m_pProj.GetLevel() - 1))
	    {
		    Point2D firstPt = m_pProj.PDisplay2RP(vPoint.X, vPoint.Y);
    		
		    int nCurLevel = m_pProj.GetLevel();
		    m_pProj.SetLevel(nCurLevel-1);

		    Point2D latterPt = m_pProj.PDisplay2RP(vPoint.X, vPoint.Y);
		    Point2D centerPt = m_pProj.GetCenterPoint();

		    centerPt.x += firstPt.x - latterPt.x;
		    centerPt.y += firstPt.y - latterPt.y;
    		
		    m_pProj.SetCenter(centerPt);
		    return true;
	    }

	    return false;
    }

    public void ZoomCenter(Point2D center, int nLevel)
    {
	    m_pProj.SetCenter(center);

	    if(nLevel == -1)
		    nLevel = _MAX_CLOSE_UP_LEVEL;

	    nLevel = Math.Max(nLevel, m_pProj.GetLevel());

	    m_pProj.SetLevel(nLevel);
    }
}
